package test.demo;

import tech.waterism.modelbase.PredictBase;
import tech.waterism.modelbase.PredictResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


import java.util.*;


/**
 * 大伙房模型（大伙房产汇流）
 *
 * @author 初京刚
 * @version 1.0
 * @date 2022-1-7
 */
public class DHF_dhf extends PredictBase {

    /**
     * 圆周率
     */
    final static double PAI = (Math.PI);
    /**
     * 上层蓄水容量
     */
    private double s0;
    /**
     * 下层蓄水容量
     */
    private double u0;
    /**
     * 地下水蓄水容量，即下层蓄水容量与地下水库蓄水容量之和
     */
    private double d0;
    /**
     * 流域蒸散发折算系数
     */
    private double Kc;

    /**
     * yL与RL的比值
     */
    private double Kw;

    /**
     * 点的下层下渗曲线的曲率系数
     */
    private double k2;
    /**
     * 不透水面积比例
     */
    private double g;
    /**
     * 表层蓄水容量空间分布曲线形状参数
     */
    private double a;
    /**
     * 流域内下渗率抛物线形状系数（总下渗或下层下渗）
     */
    private double B;
    /**
     * 初始流域表层平均蓄水量
     */
    private double sa0;
    /**
     * 初始流域下层平均蓄水量
     */
    private double ua0;
    /**
     * 初始前期影响雨量
     */
    private double ya0;
    /**
     * 表层蓄水量
     */
    private double[] sa;
    /**
     * 下层蓄水量
     */
    private double[] ua;
    /**
     * 前期影响雨量
     */
    private double[] ya;
    /**
     * 地下水库下渗强度
     */
    private double[] rL;
    /**
     * 流域 月蒸发量（mm）
     */
    private double[] ES;

    /**
     * 流域 时段蒸发量（mm）
     */
    private double[] floodE;
    /**
     * 地表汇流曲线形状参数
     */
    private double[] AA;
    /**
     * 地表汇流曲线形状参数
     */
    private double[] DD;
    /**
     * 地表汇流曲线形状参数
     */
    private double[] CC;
    /**
     * 地表汇流曲线比例系数
     */
    private double[] K3;
    /**
     * 地表汇流曲线参数，描述峰现时间
     */
    private double[] COE;
    private double COEL;//GHJ新加
    /**
     * 特征河长比例系数，为待定参数
     */
    private double B0;
    /**
     * 汇流曲线底宽求解指数，为待定参数
     */
    private double K0;
    /**
     * 前期净雨影响衰减系数
     */
    private double Ka;
    /**
     * 地下径流与地面壤中流汇流曲线底宽的比例系数
     */
    private double N;
    /**
     * 流域最大河长
     */
    private double L;
    /**
     * 地下汇流曲线形状参数
     */
    private double AAL;
    /**
     * 地下汇流曲线形状参数
     */
    private double DDL;
    /**
     * 地下汇流曲线形状参数
     */
    private double CCL;
    /**
     * 地下汇流曲线比例系数
     */
    private double K3L;
    /**
     * 地表汇流曲线底宽
     */
    private double Tm;
    //private double[]Tm;
    /**
     * 特征河长
     */
    //private double LB;
    private double LB;
    /**
     * 模拟总产流
     */
    private double[] RunoffSim;

    /**
     * 模拟总径流
     */
    private double[] QSim;

    /**
     * 不透水面积产流
     */
    private double[] y0;

    /**
     * 净雨
     */
    private double[] PE;

    /**
     * 分水源-地面壤中流
     */
    private double[] yu;

    /**
     * 分水源-地下径流
     */
    private double[] yL;

    /**
     * 地表壤中流与地下径流之和
     */
    private double[] y;

    /**
     * 汇流-地面壤中流
     */
    private double[] qs;

    /**
     * 汇流-地下径流
     */
    private double[] ql;

    /**
     * 降水时间
     */
    private Date[] floodTm;

    /**
     * 降水量
     */
    private double[] floodDrp;

    /**
     * 降水序列长度
     */
    private Integer floodRainRange;

    /**
     * 降水时段长
     */
    private double timeInterval;

    /**
     * 流域面积
     */
    private double Area;

    /**
     * 流域表层、下层平均蓄量初值、前期影响雨量初值
     */
    private double[] WInitialDay;

    private double SDD;
    private double ZDD;
    private double XDD;
    private double A;
    private double F;
    private double K2;
    private double G;
    private double K;
    private int shangyougeshu;
    private int zhongyougeshu;
    private int xiayougeshu;
    private double shangyouquanzhong;
    private double zhongyouquanzhong;
    private int panbie;
    private double xiayouquanzhong;
    private double KA;
    private double SCC;
    private double ZCC;
    private double XCC;
    private double SCOE;
    private double ZCOE;
    private double XCOE;
    private double SAA;
    private double ZAA;
    private double XAA;
    private double SK3;
    private double ZK3;
    private double XK3;
    private double SA0;
    private double UA0;
    private double YA0;
    private double D0;
    private double KW;
    private double clen;
    private double S0;
    private double U0;
    //0718GHJ


    public DHF_dhf(Map<String, String> data) {
        super();
        sa0 = Double.parseDouble(data.get("SA0"));
        ua0 = Double.parseDouble(data.get("UA0"));
        ya0 = Double.parseDouble(data.get("YA0"));
        WInitialDay = new double[]{sa0, ua0, ya0};

        s0 = Double.parseDouble(data.get("S0"));
        s0 = Double.parseDouble(data.get("S0"));
        u0 = Double.parseDouble(data.get("U0"));
        d0 = Double.parseDouble(data.get("D0"));
        k2 = Double.parseDouble(data.get("K2"));
        Ka = Double.parseDouble(data.get("KA"));
        Kc = Double.parseDouble(data.get("K"));
        Kw = Double.parseDouble(data.get("KW"));
        g = Double.parseDouble(data.get("G"));
        a = Double.parseDouble(data.get("A"));
        B = Double.parseDouble(data.get("B"));
        B0 = Double.parseDouble(data.get("B0"));
        K0 = Double.parseDouble(data.get("K0"));
        N = Double.parseDouble(data.get("N"));
        L = Double.parseDouble(data.get("L"));
        COEL = Double.parseDouble(data.get("COEL"));//GHJ新加，地下汇流的时候使用的参数
        DDL = Double.parseDouble(data.get("DDL"));
        CCL = Double.parseDouble(data.get("CCL"));
        AAL = Double.parseDouble(data.get("AAL"));//GHJ新加，地下汇流的时候使用的参数
        K3L = Double.parseDouble(data.get("K3L"));//GHJ新加，地下汇流的时候使用的参数
        Area = Double.parseDouble(data.get("F"));

        ES = JSON.parseObject(data.get("ES"), double[].class);
        floodTm = JSON.parseObject(data.get("dt"), Date[].class);// input[i].data.dt
        SDD = Double.parseDouble(data.get("SDD"));
        ZDD = Double.parseDouble(data.get("ZDD"));
        XDD = Double.parseDouble(data.get("XDD"));
        A = Double.parseDouble(data.get("A"));
        F = Double.parseDouble(data.get("F"));
        K2 = Double.parseDouble(data.get("K2"));
        G = Double.parseDouble(data.get("G"));
        K = Double.parseDouble(data.get("K"));
        shangyougeshu = Integer.parseInt(data.get("shangyougeshu"));
        zhongyougeshu = Integer.parseInt(data.get("zhongyougeshu"));
        xiayougeshu = Integer.parseInt(data.get("xiayougeshu"));
        panbie = Integer.parseInt(data.get("panbie"));
        xiayouquanzhong = Double.parseDouble(data.get("xiayouquanzhong"));
        zhongyouquanzhong = Double.parseDouble(data.get("zhongyouquanzhong"));
        shangyouquanzhong = Double.parseDouble(data.get("shangyouquanzhong"));
        KA = Double.parseDouble(data.get("KA"));
        SCC = Double.parseDouble(data.get("SCC"));
        ZCC = Double.parseDouble(data.get("ZCC"));
        XCC = Double.parseDouble(data.get("XCC"));
        SCOE = Double.parseDouble(data.get("SCOE"));
        ZCOE = Double.parseDouble(data.get("ZCOE"));
        XCOE = Double.parseDouble(data.get("XCOE"));
        SAA = Double.parseDouble(data.get("SAA"));
        ZAA = Double.parseDouble(data.get("ZAA"));
        XAA = Double.parseDouble(data.get("XAA"));
        SK3 = Double.parseDouble(data.get("SK3"));
        ZK3 = Double.parseDouble(data.get("ZK3"));
        XK3 = Double.parseDouble(data.get("XK3"));
        SA0 = Double.parseDouble(data.get("SA0"));
        UA0 = Double.parseDouble(data.get("UA0"));
        YA0 = Double.parseDouble(data.get("YA0"));
        D0 = Double.parseDouble(data.get("D0"));
        KW = Double.parseDouble(data.get("KW"));
        clen = Double.parseDouble(data.get("clen"));
        S0 = Double.parseDouble(data.get("S0"));
        U0 = Double.parseDouble(data.get("U0"));

        if (!data.containsKey("ptRain")) {
            return;
        }
        List<JSONObject> ptRain = JSON.parseObject(data.get("ptRain"), List.class);
        Map<String, double[]> rainMap = new HashMap<>();
        for (JSONObject pt : ptRain) {
            String pstcd = pt.get("pstcd").toString();
            double[] rain = JSON.parseObject(pt.get("rain").toString(), double[].class);
            rainMap.put(pstcd, rain);
        }
        //Ghj修改 floodDrp = JSON.parseObject(data.get("rain"), double[].class);// input[i].data.rain
        //修改开始替换flooddrop
        try {
            // 读取站码列表
            List<String> zhanmaList = new LinkedList<>();
            zhanmaList.add("21121184");
            zhanmaList.add("21121284");
            zhanmaList.add("21121384");
            zhanmaList.add("21121584");
            zhanmaList.add("21122184");
            zhanmaList.add("21122384");
            zhanmaList.add("21122484");
            zhanmaList.add("21122584");
            zhanmaList.add("21124184");
            zhanmaList.add("21123184");
            zhanmaList.add("21123284");
            zhanmaList.add("21124284");
            zhanmaList.add("21124384");
            zhanmaList.add("21128084");
            // 验证站码数量是否足够
            int total = shangyougeshu + zhongyougeshu + xiayougeshu;
            if (zhanmaList.size() < total) {
                throw new RuntimeException("站码数量不足");
            }

            // 划分上、中、下游站点的降雨数据
            List<double[]> shangList = new ArrayList<>();
            List<double[]> zhongList = new ArrayList<>();
            List<double[]> xiaList = new ArrayList<>();

            for (int i = 0; i < shangyougeshu; i++) {
                String code = zhanmaList.get(i);
                shangList.add(rainMap.get(code));
            }

            for (int i = 0; i < zhongyougeshu; i++) {
                String code = zhanmaList.get(shangyougeshu + i);
                zhongList.add(rainMap.get(code));
            }

            for (int i = 0; i < xiayougeshu; i++) {
                String code = zhanmaList.get(shangyougeshu + zhongyougeshu + i);
                xiaList.add(rainMap.get(code));
            }

            // 获取降雨数据长度
            int len = rainMap.get(zhanmaList.get(0)).length;

            // 初始化求和数组
            double[] sum1 = new double[len];
            double[] sum2 = new double[len];
            double[] sum3 = new double[len];

            // 分别对上游、中游、下游的降雨数据求和
           /* for (double[] arr : shangList) {
                for (int j = 0; j < len; j++) {
                    sum1[j] += arr[j];
                }
            }

            for (double[] arr : zhongList) {
                for (int j = 0; j < len; j++) {
                    sum2[j] += arr[j];
                }
            }

            for (double[] arr : xiaList) {
                for (int j = 0; j < len; j++) {
                    sum3[j] += arr[j];
                }
            }

            // 分别求平均
            for (int j = 0; j < len; j++) {
                sum1[j] /= shangyougeshu;
                sum2[j] /= zhongCount;
                sum3[j] /= xiayougeshu;
            }

            // 计算最终的 floodDrp 数组
            floodDrp = new double[len];
            for (int j = 0; j < len; j++) {
                floodDrp[j] = sum1[j] + sum2[j] + sum3[j];*/
            for (double[] arr : shangList) {
                for (int j = 0; j < len; j++) {
                    sum1[j] += arr[j];
                }
            }

            for (double[] arr : zhongList) {
                for (int j = 0; j < len; j++) {
                    sum2[j] += arr[j];
                }
            }

            for (double[] arr : xiaList) {
                for (int j = 0; j < len; j++) {
                    sum3[j] += arr[j];
                }
            }

            // 计算最终的 floodDrp 数组（统一求平均）
            floodDrp = new double[len];
            int totalCount = shangyougeshu + zhongyougeshu + xiayougeshu;
            for (int j = 0; j < len; j++) {
                floodDrp[j] = (sum1[j] + sum2[j] + sum3[j]) / totalCount;
            }
            System.out.println("floodDrp: " + Arrays.toString(floodDrp));

//==============================从这里开始新的修改==========================================0717ghj
            //新增部分开始// 1. 分别计算上游、中游、下游的总降雨量（所有时段雨量求和）

           /* double ku1 = 0.0;
            double ku2 = 0.0;
            double ku3 = 0.0;

            for (double val : sum1) {
                ku1 += val;
            }
            for (double val : sum2) {
                ku2 += val;
            }
            for (double val : sum3) {
                ku3 += val;
            }

            System.out.println("上游总雨量 ku1: " + ku1);
            System.out.println("中游总雨量 ku2: " + ku2);
            System.out.println("下游总雨量 ku3: " + ku3);

            System.out.println("上游权重: " + shangyouquanzhong);
            System.out.println("中游权重: " + zhongyouquanzhong);
            System.out.println("下游权重: " + xiayouquanzhong);

            // 3. 计算加权总雨量
            double sumku = ku1 * shangyouquanzhong + ku2 * zhongyouquanzhong + ku3 * xiayouquanzhong;

            System.out.println("加权总雨量 sumku: " + sumku);
            //新增部分结束
            //增加判断条件获取AA DD CC K3 COE的取值
            double K22 = ku1 / sumku;
            double k33 = ku2 / sumku;
            double k44 = ku3 / sumku;

            if (k44 > 1.2) {
                DD =XDD;
                CC = XCC;
                AA = XAA;
                COE = XCOE;
                K3 = XK3;
            } else if (K22 > 1.5) {
                DD = SDD ;
                CC = SCC;
                AA = SAA;
                COE = SCOE;
                K3 = SK3;
            } else {
                DD = ZDD;
                CC = ZCC;
                AA = ZAA;
                COE = ZCOE;
                K3 = ZK3;
            }
            System.out.println("最终获取的DD值: " + DD);
            System.out.println("最终获取的CC值: " + CC);
            System.out.println("最终获取的AA值: " + AA);
            System.out.println("最终获取的COE值: " + COE);
            System.out.println("最终获取的K3值: " + K3);
            //增加判断条件获取AA DD CC K3 COE的取值*/

            // 初始化结果数组（长度与时段数一致）=============================================ghj0717
            int timeSteps = sum1.length;
            double[] AA = new double[timeSteps];
            double[] DD = new double[timeSteps];
            double[] CC = new double[timeSteps];
            double[] COE = new double[timeSteps];
            double[] K3 = new double[timeSteps];

// 遍历每个时段
            for (int i = 0; i < timeSteps; i++) {
                double ku1 = sum1[i]; // 上游第i时段雨量
                double ku2 = sum2[i]; // 中游第i时段雨量
                double ku3 = sum3[i]; // 下游第i时段雨量

                double sumku = ku1 * shangyouquanzhong + ku2 * zhongyouquanzhong + ku3 * xiayouquanzhong;

                // 避免除以0的异常情况
                if (sumku == 0) {
                    DD[i] = SDD;
                    CC[i] = SCC;
                    AA[i] = SAA;
                    COE[i] = SCOE;
                    K3[i] = SK3;
                    continue;
                }

                double K22 = ku1 / sumku;
                double k33 = ku2 / sumku;
                double k44 = ku3 / sumku;

                if (k44 > 1.2) {
                    // 使用下游参数
                    DD[i] = XDD;
                    CC[i] = XCC;
                    AA[i] = XAA;
                    COE[i] = XCOE;
                    K3[i] = XK3;
                } else if (K22 > 1.5) {
                    // 使用上游参数
                    DD[i] = SDD;
                    CC[i] = SCC;
                    AA[i] = SAA;
                    COE[i] = SCOE;
                    K3[i] = SK3;
                } else {
                    // 使用中游参数
                    DD[i] = ZDD;
                    CC[i] = ZCC;
                    AA[i] = ZAA;
                    COE[i] = ZCOE;
                    K3[i] = ZK3;
                }
            }
// 保存计算得到的数组到成员变量
            this.AA = AA;
            this.DD = DD;
            this.CC = CC;
            this.COE = COE;
            this.K3 = K3;

            System.out.println("AA: " + Arrays.toString(AA));
            System.out.println("DD: " + Arrays.toString(DD));
            System.out.println("CC: " + Arrays.toString(CC));
            System.out.println("COE: " + Arrays.toString(COE));
            System.out.println("K3: " + Arrays.toString(K3));

        } catch (NumberFormatException e) {
            System.err.println("站点个数解析失败: " + e.getMessage());
            floodDrp = new double[0];
        } catch (Exception e) {
            System.err.println("处理降雨数据时出现异常: " + e.getMessage());
            floodDrp = new double[0];
        }
        // ... existing code ...

        floodE = JSON.parseObject(data.get("evaporation"), double[].class);  // input[i].data.evaporation
        floodRainRange = floodDrp.length;
        timeInterval = Double.parseDouble(data.get("clen"));                  // index.clen
        RunoffSim = new double[floodRainRange];
        QSim = new double[floodRainRange];
        y0 = new double[floodRainRange];
        PE = new double[floodRainRange];
        yu = new double[floodRainRange];
        yL = new double[floodRainRange];
        y = new double[floodRainRange];
        rL = new double[floodRainRange];
        qs = new double[floodRainRange];
        ql = new double[floodRainRange];
    }

    public static void main(String[] args) {
        String a = "{"
                + "\"SDD\":\"1\",\"ZDD\":\"1\",\"XDD\":\"0.5\",\"A\":\"4.13\",\"B\":\"2.00\",\"K0\":\"0.43\",\"F\":\"5469.643\","
                + "\"K2\":\"0.6\",\"G\":\"0.05\",\"K\":\"0.84\",\"L\":\"155.763\",\"DDL\":\"0.5\",\"N\":\"2.5\",\"panbie\":\"1\","
                + "\"shangyougeshu\":\"5\",\"zhongyougeshu\":\"6\",\"xiayougeshu\":\"3\","
                + "\"shangyouquanzhong\":\"0.42\",\"zhongyouquanzhong\":\"0.38\",\"xiayouquanzhong\":\"0.2\","
                + "\"zhanma\":\"[\\\"21121184\\\",\\\"21121284\\\",\\\"21121384\\\",\\\"21121584\\\",\\\"21122184\\\",\\\"21122384\\\",\\\"21122484\\\",\\\"21122584\\\",\\\"21124184\\\",\\\"21123184\\\",\\\"21123284\\\",\\\"21124284\\\",\\\"21124384\\\",\\\"21128084\\\"]\","
                + "\"dt\":\"[\\\"2005-07-12 11:00:00\\\",\\\"2005-07-12 14:00:00\\\",\\\"2005-07-12 17:00:00\\\",\\\"2005-07-12 20:00:00\\\",\\\"2005-07-12 23:00:00\\\",\\\"2005-07-13 02:00:00\\\",\\\"2005-07-13 05:00:00\\\",\\\"2005-07-13 08:00:00\\\",\\\"2005-07-13 11:00:00\\\",\\\"2005-07-13 14:00:00\\\",\\\"2005-07-13 17:00:00\\\",\\\"2005-07-13 20:00:00\\\",\\\"2005-07-13 23:00:00\\\",\\\"2005-07-14 02:00:00\\\",\\\"2005-07-14 05:00:00\\\",\\\"2005-07-14 08:00:00\\\",\\\"2005-07-14 11:00:00\\\",\\\"2005-07-14 14:00:00\\\",\\\"2005-07-14 17:00:00\\\",\\\"2005-07-14 20:00:00\\\",\\\"2005-07-14 23:00:00\\\",\\\"2005-07-15 02:00:00\\\",\\\"2005-07-15 05:00:00\\\",\\\"2005-07-15 08:00:00\\\",\\\"2005-07-15 11:00:00\\\",\\\"2005-07-15 14:00:00\\\",\\\"2005-07-15 17:00:00\\\",\\\"2005-07-15 20:00:00\\\",\\\"2005-07-15 23:00:00\\\",\\\"2005-07-16 02:00:00\\\",\\\"2005-07-16 05:00:00\\\",\\\"2005-07-16 08:00:00\\\",\\\"2005-07-16 11:00:00\\\",\\\"2005-07-16 14:00:00\\\",\\\"2005-07-16 17:00:00\\\",\\\"2005-07-16 20:00:00\\\",\\\"2005-07-16 23:00:00\\\",\\\"2005-07-17 02:00:00\\\",\\\"2005-07-17 05:00:00\\\",\\\"2005-07-17 08:00:00\\\",\\\"2005-07-17 11:00:00\\\",\\\"2005-07-17 14:00:00\\\",\\\"2005-07-17 17:00:00\\\",\\\"2005-07-17 20:00:00\\\",\\\"2005-07-17 23:00:00\\\",\\\"2005-07-18 02:00:00\\\",\\\"2005-07-18 05:00:00\\\",\\\"2005-07-18 08:00:00\\\",\\\"2005-07-18 11:00:00\\\",\\\"2005-07-18 14:00:00\\\",\\\"2005-07-18 17:00:00\\\",\\\"2005-07-18 20:00:00\\\",\\\"2005-07-18 23:00:00\\\",\\\"2005-07-19 02:00:00\\\",\\\"2005-07-19 05:00:00\\\",\\\"2005-07-19 08:00:00\\\",\\\"2005-07-19 11:00:00\\\"]\","
                + "\"ptRain\":\"[{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21121184\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21121284\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21121384\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21121584\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21122184\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21122384\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21122484\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21122584\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21124184\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21123184\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21123284\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21124284\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21124384\\\"}," +
                "{\\\"rain\\\":\\\"[0.3 ,0.4 ,0.6 ,0.0 ,2.3 ,8.0 ,16.0 ,2.5 ,0.3 ,0.4 ,0.3 ,0.0 ,0.0 ,0.0 ,0.0 ,8.0 ,9.0 ,7.0 ,0.1 ,0.1 ,6.0 ,9.0 ,12.0 ,8.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ]\\\",\\\"pstcd\\\":\\\"21128084\\\"}]\","
                + "\"KA\":\"0.84\",\"COEL\":\"0.24\",\"SCC\":\"3\",\"ZCC\":\"3\",\"XCC\":\"2\",\"SCOE\":\"0.3\",\"ZCOE\":\"0.24\",\"XCOE\":\"0.18\","
                + "\"SAA\":\"2.18\",\"ZAA\":\"3.19\",\"XAA\":\"4.74\",\"SK3\":\"20822\",\"ZK3\":\"56728\",\"XK3\":\"161927\","
                + "\"SA0\":\"20\",\"UA0\":\"23.9\",\"start\":\"\\\"2005-7-12 11:00:00\\\"\",\"YA0\":\"50\","
                + "\"D0\":\"130\",\"KW\":\"0.84\",\"CCL\":\"1\",\"AAL\":\"3.53\",\"K3L\":\"31052\","
                + "\"ES\":\"[23.8,23.2,33.7,53,66.6,78.9,122.3,113.9,90.8,62.9,46.2,34.1]\","
                + "\"B0\":\"0.83\",\"q\":\"[]\",\"runoffSim\":\"[]\",\"U0\":\"70\",\"clen\":\"3\",\"S0\":\"40\""
                + "}";
        Map data = JSON.parseObject(a, Map.class);
        DHF_dhf obj = new DHF_dhf(data);
        System.out.println(obj.predict());
    }

    @Override
    public void init() {

    }

    @Override
    public PredictResult predict() {
        PredictResult result = new PredictResult();
        if (floodDrp == null) {
            result.setQSim(new double[1]);
            return result;
        }
        Map<String, double[]> map = DHF_Model();

        double[][] RSim = new double[4][];
        //不透水面积产流
        RSim[0] = map.get("y0");
        //流域地表壤中流
        RSim[1] = map.get("yu");
        //流域地下径流
        RSim[2] = map.get("yL");
        //流域地表壤中流与地下径流之和
        RSim[3] = map.get("y");

        //流域面积总产流，不透水面积产流y0[j]+ 流域表层径流yu[j] +  流域地下径流yL[j];
        result.setRunoffSim(map.get("runoffSim"));
        result.setRSim(RSim);
        //汇流计算结果
        result.setQSim(map.get("QSim"));

        // 更新状态
        List<String> sap = toStringList(sa);
        List<String> uap = toStringList(ua);
        List<String> yap = toStringList(ya);
        //        List<String> rLp = toStringList(rL);
        //        List<String> qsp = toStringList(qs);
        //        List<String> qlp = toStringList(ql);

        Map<String, List<String>> status = new HashMap<>();
        //表层蓄力量
        status.put("SA0", sap);
        //下层蓄水量
        status.put("UA0", uap);
        //前期影响雨量
        status.put("YA0", yap);
        //        //地下水库下渗强度
        //        status.put("rLp", rLp);
        //        //汇流-地面壤中流
        //        status.put("qsp", qsp);
        //        //汇流-地下径流
        //        status.put("qlp", qlp);
        result.setNewStatus(status);

        return result;
    }


    /**
     * 大伙房产流
     *
     * @return 净雨过程
     */
    private void dhf_runoff() {
        sa = new double[floodRainRange + 1];
        ua = new double[floodRainRange + 1];
        ya = new double[floodRainRange + 1];

        sa[0] = WInitialDay[0];
        ua[0] = WInitialDay[1];
        ya[0] = WInitialDay[2];

        double Pc;// 净渗雨强，净雨-不透水产流
        double EDt; // EDt为蒸散发，等于Kc * E（实测蒸发，即ES[]或时段）
        double Sm; // 与sa值相对应的纵坐标值（流域单点表层最大蓄水量）
        double rr; // 下渗强度
        double un; // 与ua值相对应的纵坐标值（流域单点下层最大下渗量）
        double dn; // 与da（地下水库蓄水量与下层蓄水里之和）值相对应的纵坐标值（流域单点下层与地下水库的最大下渗量）
        double Ec; // 土壤表层时段最大蒸散发
        double Eb; // 土壤表层累积最大蒸散发
        double EL; // 下层蒸散发
        double Eu; // 表层可蒸发量
        double Z1, Z2;

        if (sa[0] > s0)
            sa[0] = s0;
        if (ua[0] > u0)
            ua[0] = u0;
        //        sa[0] = sa0; // 初始表层蓄水量
        //        ua[0] = ua0; // 初始下层蓄水量
        //        ya[0] = ya0; // 初始全部径流
        //        double s0 = s00;
        //        double u0 = u00;
        for (int i = 0; i < floodRainRange; i++) {
            //            s0 = s0 + timeStep/day * sd; // 表示现在时刻的上层蓄水容量（计算值）， sd 表层蓄水容量增量
            //            u0 = u0 + timeStep/day * ud;
            if (sa[i] > s0) {
                sa[i] = s0;
            }
            if (ua[i] > u0) {
                ua[i] = u0;
            }
            yu[i] = 0.0;  //地面壤中流
            yL[i] = 0.0; //地下径流
            Eb = 0.0; //初始化Eb

            //以下计算蒸发量
            //            EDt = f_emt(tm[i], rain[i]); //E--雨间蒸散发量
            if (floodE == null || floodE.length != floodRainRange) {
                EDt = Kc * calcEvaporationPotential(floodTm[i], timeInterval);
            } else {
                EDt = Kc * floodE[i];
            }

            PE[i] = floodDrp[i] - EDt; //PE--净雨强,floodDrp[i]-第i时段的降雨量
            y0[i] = g * PE[i]; //y0--不透水面积上的直接径流
            Pc = PE[i] - y0[i]; //Pc--净渗雨强

            //地面壤中流和地下径流之和y的计算
            //-----------当降雨量超过流域蒸发能力时，即净渗雨强Pc>0------------//
            if (Pc > 0.0) {
                double temp = (Math.pow(1 - sa[i] / s0, 1 / a));
                Sm = a * s0 * (1 - temp); // 2-103,Sm--相应于Sa的点蓄水量（流域单点表层最大蓄水量）
                if (Sm + Pc < a * s0) {
                    temp = (Math.pow(1 - (Sm + Pc) / (a * s0), a));
                    rr = Pc + sa[i] - s0 + s0 * temp; //2-104,R--下渗强度
                } else {
                    rr = Pc - (s0 - sa[i]); //2-96
                }
                /*********************表层***********************/
                temp = (Math.pow(1 - ua[i] / u0, 1 / B));
                un = B * u0 * (1 - temp); //2-128
                temp = (Math.pow(1 - ua[i] / u0, u0 / (B * d0)));
                dn = B * d0 * (1 - temp); //2-133

                Z1 = (1 - Math.exp(-k2 * timeInterval * u0 / d0)); //2-119
                Z2 = (1 - Math.exp(-k2 * timeInterval)); //2-120
                //地面壤中流和地下径流之和
                if (rr + Z2 * un < Z2 * B * u0) {
                    temp = (Math.pow((1 - (Z2 * un + rr) / (Z2 * B * u0)), B));
                    y[i] = rr + Z2 * (ua[i] - u0) + Z2 * u0 * temp; //2-129
                } else {
                    y[i] = rr + Z2 * (ua[i] - u0); //2-130
                }
                //求地面壤中流yu
                temp = (Math.pow(1 - ua[i] / u0, u0 / d0));
                if (Z1 * dn + rr < Z1 * B * d0) {
                    double temp1 = 1 - (Z1 * dn + rr) / (Z1 * B * d0);
                    double temp2 = (Math.pow(temp1, B));
                    yu[i] = rr - Z1 * d0 * temp + Z1 * d0 * temp2; //2-131
                } else {
                    yu[i] = rr - Z1 * d0 * temp; //2-132
                }
                //求地下径流yL
                yL[i] = (y[i] - yu[i]) * Kw; //2-134

                /*需保留最后一个时段末的状态值，去掉时段初值限制条件*/
                //               if(i + 1 < floodRainRange) {
                //表面蓄水量计算sa[i+1]
                if (Sm + Pc < a * s0) {
                    double temp1 = 1 - (Sm + Pc) / (a * s0);
                    double temp2 = (Math.pow(temp1, a));
                    sa[i + 1] = s0 * (1 - temp2); //2-138
                } else {
                    sa[i + 1] = sa[i] + Pc - rr; //2-140
                }
                if (sa[i + 1] > s0) {
                    sa[i + 1] = s0; //表层蓄水量不能超过超过表层蓄水容量，即饱和状态
                }
                //下层土壤蓄水量ua[i+1]
                ua[i + 1] = ua[i] + rr - y[i]; //2-141
                if (ua[i + 1] > u0) {
                    ua[i + 1] = u0;
                }
                //                }
                Eb = 0.0;
            } else {//---------当日流域平均降雨量小于流域平均蒸散发能力，即P<Ed时--------//
                rr = 0.0; //下渗强度
                Ec = EDt - floodDrp[i]; //2-144
                Eb = Eb + Ec; //2-145
                //                if (Eb > sa[0]) {
                //                    Eb = sa[0]; //限制蒸发深度
                //                }

                //表层可蒸发量Eu,两个假定
                double temp1 = (Math.pow(1 - (Eb - Ec) / (a * s0), a));
                double temp2 = (Math.pow(1 - Eb / (a * s0), a));
                //Eu = s0 * (temp1 - temp2); //2-146
                ////////防止出现负数///////////////
                if (Eb / (a * s0) <= 0.999999 & (Eb - Ec) / (a * s0) <= 0.999999) {
                    Eu = s0 * (temp1 - temp2); // 2-146
                } else if (Eb / (a * s0) >= 1.00001 & (Eb - Ec) / (a * s0) <= 0.999999) {
                    Eu = s0 * Math.pow(temp1, a);
                } else {
                    Eu = 0.00001;
                }

                if (sa[i] - Eu < 0.0) {
                    EL = (Ec - sa[i]) * ua[i] / u0; //2-149
                    if (i + 1 < floodRainRange) {
                        sa[i + 1] = 0.0;
                        ua[i + 1] = ua[i] - EL; //2-150
                        if (ua[i + 1] < 0.0) {
                            ua[i + 1] = 0.0;
                        }
                    }
                } else {
                    EL = (Ec - Eu) * ua[i] / u0; //2-148
                    if (i + 1 < floodRainRange) {
                        sa[i + 1] = sa[i] - Eu; //2-147
                        ua[i + 1] = ua[i] - EL; //2-150
                        if (ua[i + 1] < 0.0) {
                            ua[i + 1] = 0.0;
                        }
                    }
                }

                y[i] = 0.0; //表层径流和地下径流之和
                y0[i] = 0.0; //直接径流
                yu[i] = 0.0; //地面壤中流
                yL[i] = 0.0; //地下径流
            }

            /*需保留最后一个时段末的状态值，去掉时段初值限制条件*/
            //            if(i + 1 < floodRainRange) {
            if (sa[i + 1] > s0) {
                sa[i + 1] = s0; // 表层蓄水量不能超过表层蓄水容量，即饱和状态
            }
            if (sa[i + 1] < 0) {
                sa[i + 1] = 0;
            }
            if (ua[i + 1] < 0) {
                ua[i + 1] = 0f;
            }
            if (ua[i + 1] > u0) {
                ua[i + 1] = u0;
                // System.out.println("**ua["+(i+1)+"]"+ua[i+1]);
            }
            //            }
        }
    }

    public void dhf_flow() {
        int TT = 0; //地下径流汇流曲线宽度
        int TS = 0; //地表峰现时间
        int TL = 0; //总汇流曲线宽度
        double w0 = Area /
                (3.6 * timeInterval); //R 单位转换系数（km2/h = 1000000 m2/ 3600 s = 1000m2/3.6s，km2·mm/h = 1000000 * 0.001 m3/
        // 3600 s = m3/3.6s）
        for (int i = 0; i < floodRainRange; i++) {
            // rL[i] = r[i] * c3; //c3 = 0.15f,c3修正参数，曲线拟合更好
            // Tm是时段降雨与前期影响净雨（已产生的径流）的函数
            if (ya[i] < 0.5) {
                ya[i] = 0.5; // 防止计算
            }
            double tempTm = (Math.pow(ya[i] + RunoffSim[i], -K0));
            LB = L / B0;
            Tm = LB * tempTm; // 2-152
            //ya0 = K * (ya0 + RunoffSim[i]); // 2-153

            TT = (int) (N * Tm);
            TS = (int) (COE[i] * Tm);
            //GHJ将coe换成了COEL,对AAL和K3L进行判别是从外部获取还是使用计算
            boolean shouldCalculate = true;


            // 提取 panbie 参数


            if (panbie == 1) {
                shouldCalculate = false;
                System.out.println("跳过AAL和K3L计算，使用外部传入值:");
                System.out.println("AAL = " + AAL);
                System.out.println("K3L = " + K3L);

            } else {
                System.out.println("未在文件中找到 panbie 参数，默认执行计算");
            }

            if (shouldCalculate) {
                K3L = 0.0; // 初始化K3L
                double tempAAL = Math.pow(PAI * COE[i], DD[i] - 1);
                AAL = CCL / (DDL * tempAAL * Math.tan(PAI * COE[i])); // 计算 AA
                for (int j = 0; j < Tm; j++) {
                    double tmp = Math.pow(PAI * j / Tm, DDL);
                    double tmp1 = Math.pow(Math.sin(PAI * j / Tm), CCL);
                    K3L += Math.exp(-AAL * tmp) * tmp1; // 这里原代码可能是笔误，应该是 K3L 累加
                    System.out.println("K3L = " + K3L);
                }
                K3L = Tm * w0 / K3L;

                System.out.println("完成AAL和K3L计算:");
            }


           /* double tempAAL = (Math.pow(PAI * COEL / N, DDL - 1));
            AAL = (CCL / (DDL * tempAAL * Math.tan(PAI * COEL / N)));//2-154
            K3L = 0.0;
            for (int j = 0; j < TT; j++) {
                double tmp = Math.pow(PAI * j / TT, DDL);
                double tmp1 = Math.pow(Math.sin(PAI * j / TT), CCL);
                K3L = K3L + Math.exp(-AAL * tmp) * tmp1;
            }
            K3L = TT * w0 / K3L;//2-155*/

            //GHJ对AA和K3进行判别是从外部获取还是使用计算


            if (panbie == 1) {
                System.out.println("panbie = 1，使用已有的 AA 和 K3，不进行重新计算。");
            } else {
                K3[0] = 0.0; // 初始化K3
                double tempAA = Math.pow(PAI * COE[i], DD[i] - 1);
                AA[i] = CC[i] / (DD[i] * tempAA * Math.tan(PAI * COE[i])); // 2-154, 峰的位置参数
                for (int j = 0; j < Tm; j++) {
                    double tmp = Math.pow(PAI * j / Tm, DD[i]);
                    double tmp1 = Math.pow(Math.sin(PAI * j / Tm), CC[i]);
                    K3[i] = K3[i] + Math.exp(-AA[i] * tmp) * tmp1; // 2-155
                }
                K3[i] = Tm * w0 / K3[i]; // 相当于参考书上的K3
                System.out.println("panbie = 0，完成 AA 和 K3 的计算。");
            }

            // 无论 panbie 是多少，都打印最终使用的 AA 和 K3
            System.out.println("最终使用的 AA = " + AA[i]);
            System.out.println("最终使用的 K3 = " + K3[i]);

          /*  K3 = 0.0; // 初始化K3
            double tempAA = Math.pow(PAI * COE, DD - 1);
            AA = CC / (DD * tempAA * Math.tan(PAI * COE)); // 2-154,峰的位置参数
            for (int j = 0; j < Tm; j++) {
                double tmp = Math.pow(PAI * j / Tm, DD);
                double tmp1 = Math.pow(Math.sin(PAI * j / Tm), CC);
                K3 = K3 + Math.exp(-AA * tmp) * tmp1; // 2-155
            }
            K3 = Tm * w0 / K3; // 相等于参考书上面的K3*/

            TL = TT + TS - 1;
            if (TL <= 0) {
                TL = 0;
            }

            for (int j = 0; j < TL; j++) { // 2-151
                if (i + j == QSim.length) {// 怕越界/////////////////彭勇//////////////////
                    TL = j;
                    break;
                }
                double temp0 = PAI * j / Tm;
                double temp1 = (Math.pow(temp0, DD[i]));
                double temp2 = (Math.exp(-AA[i] * temp1));
                double temp3 = (Math.pow(Math.sin(temp0), CC[i]));
                double Qs = (RunoffSim[i] - rL[i]) * K3[i] / Tm * temp2 * temp3; // Kb=K3
                if (Double.isNaN(Qs))
                    Qs = 0;

                double temp00 = PAI * (j - TS) / TT;
                double temp10 = (Math.pow(temp00, DDL));
                double temp20 = (Math.exp(-AAL * temp10));
                double temp30 = (Math.pow(Math.sin(temp00), CCL));
                double Ql = rL[i] * K3L / TT * temp20 * temp30;
                if (j <= Tm) {
                    if (j <= TS) {
                        ql[i + j] += 0.0;
                        qs[i + j] += Qs;
                    }
                    //                    else if (j <= Tm / 2) {
                    //                        QSim[i + j] += Qs + Ql;
                    //                    }
                    else {
                        //                        Qs = (RunoffSim[i] - rL[i]) * K3 / Tm * temp2;
                        qs[i + j] += Qs;
                        ql[i + j] += Ql;
                    }
                } else {
                    qs[i + j] += 0.0;
                    //                    if (j <= TS + TT / 2) {
                    ql[i + j] += Ql;
                    //                    } else {
                    //                        Ql = rL[i] * K3L / TT * temp20;
                    //                        QSim[i + j] += Ql;
                    //                    }
                }
                QSim[i + j] = qs[i + j] + ql[i + j];
                if (QSim[i + j] < 0.0f) {
                    QSim[i + j] = 0.0f;
                }
            }
        }

    }

    /**
     * 蒸发计算
     *
     * @param date   降水时间
     * @param timeIn 时间间隔 (h)
     * @return 蒸发
     */
    private double calcEvaporationPotential(Date date, double timeIn) {
        Calendar time = Calendar.getInstance();
        time.setTime(date);
        Integer Month = time.get(Calendar.MONTH) + 1; // 获得降雨开始月份

        /*
        double[] Ev = new double[3]; // 根据月份确定该时刻小雨、中雨、大雨的蒸发能力;

        if (Month == 4)
            Ev = Eall[0];
        else if (Month == 5)
            Ev = Eall[1];
        else if (Month == 6)
            Ev = Eall[2];
        else if (Month == 7)
            Ev = Eall[3];
        else if (Month == 8)
            Ev = Eall[4];
        else if (Month == 9)
            Ev = Eall[5];
        else if (Month == 10)
            Ev = Eall[6];
        else
            System.out.println("The Evaporation of some MONTHs is not found.");

        rain = rain * 24 / timeIn;  //时段降雨量转换成日降雨量

        double[] Ms = calcRainMembership(rain); // 计算该场降雨对小雨、中雨、大雨的隶属度

        */

        double Ep = ES[Month - 1] / 30; // 月蒸发量转换成日蒸发量

        /*
        for (int i = 0; i < Ms.length; i++) { // 隶属度和蒸发数组加权求和
            Ep += Ev[i] * Ms[i];
        }
        */

        Ep = Ep * timeIn / 24; // 日蒸发量转换成时段蒸发量
        return Ep;
    }

    /**
     * 模型计算
     */
    public Map<String, double[]> DHF_Model() {
        //dhf_runoff(preFloodRainRange,preTimeInterval,preFloodTm,preFloodDrp);
        //大伙房产流
        dhf_runoff();

        for (Integer j = 0; j < floodRainRange; j++) {
            RunoffSim[j] = y[j] + y0[j]; //总径流,2-137
            if (RunoffSim[j] < 0.0) {
                RunoffSim[j] = 0.0;
            }
            rL[j] = yL[j]; //地下水库下渗强度
            if (rL[j] < 0.0) {
                rL[j] = 0.0;
            }

            /*需保留最后一个时段末的状态值，去掉时段初值限制条件*/
            //            if(j + 1 < floodRainRange) {
            ya[j + 1] = (ya[j] + RunoffSim[j]) * Ka;// 2-153
            if (ya[j + 1] < 0.0) {
                ya[j + 1] = 0.0;
            }

            //            }
        }

        //大伙房汇流
        dhf_flow();

        Map<String, double[]> simulationResult = new HashMap<>();

        simulationResult.put("rain", floodDrp);
        simulationResult.put("PE", PE);
        simulationResult.put("runoffSim", RunoffSim);
        simulationResult.put("y0", y0);
        simulationResult.put("yu", yu);
        simulationResult.put("yL", yL);
        simulationResult.put("y", y);
        simulationResult.put("qs", qs);
        simulationResult.put("ql", ql);
        simulationResult.put("QSim", QSim);

        return simulationResult;
    }

    private List<String> toStringList(double[] array0) {
        String[] array = new String[array0.length];
        for (int i = 0; i < array.length; i++) {
            array[i] = String.valueOf(array0[i]);
        }
        return Arrays.asList(array);
    }
}
